﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace SmartyOcr.Study
{
    /// <summary>
    /// SmartyOcr 的图片特征数据生成器
    /// xue8000@gmail.com 
    /// modified @2012-11-11   
    /// </summary>
    public partial class Student : Form
    {
        private readonly string CharactoristicPath = Environment.CurrentDirectory + "/SmartyOcr.Charactoristic/";
        private LinkedList<KeyValuePair<string, string>> Charactoristic { set; get; }

        /// <summary>
        /// 表示将要学习的字符
        /// </summary>
        private char[] Token { set; get; }

        public Student()
        {
            Charactoristic = CharactoristicLoader.Charactoristic;
            InitializeComponent();
        }

        private void OpenLocalImageFile()
        {
            var dialog = this.OpenFile.ShowDialog();
            if (DialogResult.OK == dialog)
            {
                this.Txt_ImagePath.Text = this.OpenFile.FileName;
                if (!string.IsNullOrEmpty(this.Txt_ImagePath.Text))
                {
                    try
                    {
                        this.Pic_ImageBox.Load(this.Txt_ImagePath.Text);
                        this.Pic_ImageBox.Width = this.Pic_ImageBox.Image.Width;
                        this.Pic_ImageBox.Height = this.Pic_ImageBox.Image.Height;
                    }
                    catch
                    {
                        MessageBox.Show(string.Format("加载图片时发生异常,指定的图片不存在!"));
                    }
                }
            }
        }
        private void OpenNetImageFile()
        {
            if (!string.IsNullOrEmpty(this.Txt_ImagePath.Text))
            {
                try
                {
                    this.Pic_ImageBox.Load(this.Txt_ImagePath.Text);
                    this.Pic_ImageBox.Width = this.Pic_ImageBox.Image.Width;
                    this.Pic_ImageBox.Height = this.Pic_ImageBox.Image.Height;
                }
                catch
                {
                    MessageBox.Show(string.Format("加载图片时发生异常,指定的图片不存在!"));
                }
            }
        }

        private void Btn_OpenFile_Click(object sender, EventArgs e)
        {
            if (this.RadioBtn_LocalIamge.Checked)
            {
                OpenLocalImageFile();
            }
            else if (this.RadioBtn_NetImage.Checked)
            {
                OpenNetImageFile();
            }
        }

        private void Btn_Study_Click(object sender, EventArgs e)
        {
            if (string.IsNullOrEmpty(this.Txt_ImageContent.Text))
            {
                MessageBox.Show("请输入图片上的文字");
                return;
            }
            var isOk = Study(this.Txt_ImagePath.Text, this.Txt_ImageContent.Text);
            if (isOk)
            {
                MessageBox.Show("学习成功");
            }
            else
            {
                MessageBox.Show("学习失败");
            }
        }

        private void RadioBtn_NetImage_CheckedChanged(object sender, EventArgs e)
        {
            this.Txt_ImagePath.Text = string.Empty;
            this.Txt_ImageContent.Text = string.Empty;
            this.Lab_FilePath.Text = "图片Url:";
            this.Btn_OpenFile.Text = "获取图片";
        }

        private void RadioBtn_LocalIamge_CheckedChanged(object sender, EventArgs e)
        {
            this.Txt_ImagePath.Text = string.Empty;
            this.Txt_ImageContent.Text = string.Empty;
            this.Lab_FilePath.Text = "文件路径:";
            this.Btn_OpenFile.Text = "打开图片";
        }

        #region//
        /// <summary>
        /// 学习方法
        /// </summary>
        /// <param name="image">图片路径</param>
        /// <param name="origin">图片上的文字内容</param>
        /// <returns>true 表示学习成功 否则 失败 </returns>
        public virtual bool Study(string image, string origin)
        {
            #region//参数检查
            if (string.IsNullOrEmpty(image) || string.IsNullOrWhiteSpace(image))
            {
                System.Diagnostics.Debug.Assert(false, "图片资源路径为空");
                return false;//此学习失败
            }
            else if (string.IsNullOrEmpty(origin) || string.IsNullOrWhiteSpace(origin))
            {
                System.Diagnostics.Debug.Assert(false, "您填写的字符为空");
                return false;//此学习失败
            }
            else
            {
                this.Token = origin.ToCharArray();
            }
            #endregion
            Uri uri = null;
            Image img = null;
            try
            {
                uri = new Uri(image);
                var client = new System.Net.WebClient();
                var stream = client.OpenRead(uri);
                img = System.Drawing.Bitmap.FromStream(stream);
            }
            catch
            {
                img = System.Drawing.Bitmap.FromFile(image);
            }
            var map = new Bitmap(img);
            SaveCharactoristic(map);
            return true;
        }
        /// <summary>
        /// 创建特征库
        /// </summary>
        /// <param name="img">Bitmap对象</param>
        protected virtual void SaveCharactoristic(Bitmap img)
        {
            //将图片内容用数字表示
            var data = ImageReader.Numerical(img, this.Token);
            #region//保存特征信息
            #region//step 1.从图片中抽取特征信息
            foreach (var item in data)
            {
                var isExists = this.Charactoristic.Where(i => i.Value == item.Value).Take(1).Count() > 0 ? true : false;
                if (!(isExists))
                {
                    this.Charactoristic.AddLast(new KeyValuePair<string, string>(item.Key, item.Value));
                }
            }
            #endregion
            #region//step 2.保存特征信息
            #region//step 2.1 判断特征文件所在目录是否存在
            if (!System.IO.Directory.Exists(this.CharactoristicPath))
            {
                System.IO.Directory.CreateDirectory(this.CharactoristicPath);
            }
            #endregion
            #region//step 2.2 序列化图片特征对象
            var serializer = new System.Runtime.Serialization.Json.DataContractJsonSerializer(this.Charactoristic.GetType());
            var json = string.Empty;
            using (var ms = new System.IO.MemoryStream())
            {
                serializer.WriteObject(ms, this.Charactoristic);
                ms.Position = 0;
                using (var reader = new System.IO.StreamReader(ms))
                {
                    json = reader.ReadToEnd();
                }
            }
            #endregion
            #region//step 2.3 写入磁盘
            var utf8 = new System.Text.UTF8Encoding(false);//utf-8 无bom
            using (var writer = new System.IO.StreamWriter(CharactoristicPath + DateTime.Now.ToString("yyyy-MM-dd") + ".rsc", false, utf8))
            {
                writer.Write(json);
            }
            #endregion
            #endregion
            #endregion
        }
        #endregion
    }
}